﻿using YiShop.Framework;
using YiShop.Framework.Cache;
using YiShop.Framework.Config;
using YiShop.Framework.Constants;
using YiShop.Framework.Utils;
using YiShop.System.Constants;

namespace YiShop.System.Services
{
    public class SysPasswordService : ITransient
    {
        private readonly ICache _cache;
        private readonly SysLogininforService _sysLogininforService;

        public SysPasswordService(ICache cache, SysLogininforService sysLogininforService)
        {
            _cache = cache;
            _sysLogininforService = sysLogininforService;
        }
        public void Validate(string username, string password, SysUserDto user)
        {
            var userConfig = AppSettings.UserConfig;
            var maxRetryCount = userConfig.MaxRetryCount;
            var lockTime = userConfig.LockTime;

            int retryCount = Convert.ToInt32(_cache.GetString(GetCacheKey(username)) ?? "0");

            if (retryCount >= maxRetryCount)
            {
                var retryLimitExceedMsg = string.Format(LoginConstants.User_Password_Retry_Limit_Exceed, maxRetryCount, lockTime);
                Task.Factory.StartNew(async () =>
                {
                    await _sysLogininforService.AddAsync(username, GlobalConstants.LOGIN_FAIL, retryLimitExceedMsg);
                });

                throw new ServiceException(retryLimitExceedMsg);
            }

            if (!MD5Encryption.Compare(password, user.Password!))
            {
                retryCount = retryCount + 1;

                var retryLimitCountMsg = string.Format(LoginConstants.User_Password_Retry_Limit_Count, retryCount);
                var notMatchMsg = LoginConstants.User_Passwrod_Not_Match;
                Task.Factory.StartNew(async () =>
                {
                    await _sysLogininforService.AddAsync(username, GlobalConstants.LOGIN_FAIL, retryLimitCountMsg);
                    await _sysLogininforService.AddAsync(username, GlobalConstants.LOGIN_FAIL, notMatchMsg);
                });

                _cache.SetString(GetCacheKey(username), retryCount.ToString(), lockTime);

                throw new ServiceException(notMatchMsg);
            }
            else
            {
                ClearLoginRecordCache(username);
            }
        }

        /// <summary>
        /// 登录账户密码错误次数缓存键名
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>缓存键key</returns>
        private string GetCacheKey(string username)
        {
            return CacheConstants.PWD_ERR_CNT_KEY + username;
        }
        public void ClearLoginRecordCache(string loginName)
        {
            _cache.Remove(GetCacheKey(loginName));
        }
    }
}
